/*
 * Copyright (C) 2009 Kristopher T Babic
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program;
 * if not, see <http://www.gnu.org/licenses>.
 */

package edu.idp.client.anim;

import java.awt.*;
import java.io.Serializable;
import java.util.Calendar;

abstract public class AnimationPath implements Serializable {

    static final long serialVersionUID = -6407621893254318074L;

    static public final int LINE = 0;
    static public final int ELLIPSE = 1;
    static public final int SINE = 2;
    static public final int SPHERE = 3;
    static public final int RANDOM = 4;

    //  static private final int   _defaultSpeed      = 1;
    static private final long _defaultMoveTime = 100L;

    private Point origin;
    private Point newOrigin;

    private long startTime = 0L;
    private long timeDiff = 0L;
    private long deltaTime = 0L;

    private Point lineVector = null;

    private Rectangle bounds = null;

    public AnimationPath() {
        this(new Point(0, 0));
    }

    public AnimationPath(Point origin) {
        setOrigin(origin);
        setStartLocation(origin);
        setStartTime();
        setDeltaMove(_defaultMoveTime);
    }

    public void setOrigin(Point origin) {
        this.origin = origin;
    }

    public Point getOrigin() {
        return this.origin;
    }

//  I may want to use this a little differently.  Right now it doesn't make all that much
//  sense.  on a set location the original location should move, so all that I should be using

    //  is origin.  I will leave it for now, but maybe later change it.  I leave that open as of now.

    protected void setStartLocation(Point loc) {
        this.newOrigin = loc;
    }

    protected Point getStartLocation() {
        return this.newOrigin;
    }

    public void setTimeDifference(long time) {
        this.timeDiff = time;
    }

    public long getTimeDifference() {
        return this.timeDiff;
    }

    public void setStartTime() {
        this.startTime = getTime();
    }

    public long getStartTime() {
        return this.startTime;
    }

    protected long getTime() {
        return Calendar.getInstance().getTime().getTime() + getTimeDifference();
    }

    public void setDeltaMove(long delta) {
        this.deltaTime = delta;
    }

    public long getDeltaMove() {
        return this.deltaTime;
    }

    protected long getCycles() {
        return (getTime() - getStartTime()) / getDeltaMove();
    }

    public void reset() {
        setStartTime();
        setStartLocation(getOrigin());
    }

    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;
    }

    public Rectangle getBounds() {
        return this.bounds;
    }

    protected Point getReflectedLocation(int x, int y) {

        Rectangle bounds = getBounds();

        if (bounds != null) {

            x = x % bounds.width;
            y = y % bounds.height;

            if (x < 0)
                x = bounds.width + x; //- x;
            if (y < 0)
                y = bounds.height + y; //- y;

        }

        return new Point(x, y);

    }

    abstract public String toString();

    abstract public Point getLocation();

    abstract public void setLocation(Point p);
//  abstract public void  setLocation ( int x, int y );
}
